﻿using Hd.AbpCoding.Permissions;
using Hd.AbpCoding.Projects.Dtos;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;

namespace Hd.AbpCoding.Projects
{

    [Authorize(AbpCodingPermissions.Project.Default)]
    public class ProjectAppService : AbpCodingAppService, IProjectAppService
    {

        protected IProjectRepository Repository { get; }
        protected IProjectManager ProjectManager { get; }

        public ProjectAppService(
            IProjectRepository projectRepository,
            IProjectManager projectManager)
        {
            Repository = projectRepository;
            ProjectManager = projectManager;
        }

        [Authorize(AbpCodingPermissions.Project.Create)]
        public async Task<ProjectDto> CreateAsync(CreateProjectDto input)
        {
            if (!await ProjectManager.CheckNameAsync(input.Name))
            {
                throw new UserFriendlyException(L["NameAlreadyExisted", input.Name]);
            }
            var project = new Project(GuidGenerator.Create(), input.Name, input.RootNamespace, input.Description);
            project = await Repository.InsertAsync(project);
            return MapDto(project);
        }

        private ProjectDto MapDto(Project project)
        {
            return ObjectMapper.Map<Project, ProjectDto>(project);
        }

        [Authorize(AbpCodingPermissions.Project.Delete)]
        public async Task DeleteAsync(Guid id)
        {
            await Repository.DeleteAsync(id);
        }

        public async Task<ProjectDto> GetAsync(Guid id)
        {
            var project = await Repository.GetAsync(id);
            return MapDto(project);
        }

        public async Task<PagedResultDto<ProjectDto>> GetListAsync(GetProjectsInput input)
        {
            var count = await Repository.GetCountAsync(input.Filter);
            var list = await Repository.GetListAsync(input.Filter, input.SkipCount, input.MaxResultCount, input.Sorting);
            return new PagedResultDto<ProjectDto>(
                count,
                list.Select(x => MapDto(x)).ToList());
        }

        [Authorize(AbpCodingPermissions.Project.Update)]
        public async Task<ProjectDto> UpdateAsync(Guid id, UpdateProjectDto input)
        {
            if (!await ProjectManager.CheckNameAsync(input.Name, id))
            {
                throw new UserFriendlyException(L["NameAlreadyExisted", input.Name]);
            }

            var project = await Repository.GetAsync(id);

            project.Name = input.Name;
            project.Description = input.Description;
            project.RootNamespace = input.RootNamespace;
            await Repository.UpdateAsync(project);

            return MapDto(project);
        }

        public Task GenerateDomainAsync(GenerateDomainDto input)
        {
            throw new NotImplementedException();
        }

        public Task GenerateProjectAsync(GenerateProjectDto input)
        {
            throw new NotImplementedException();
        }
    }
}
